package cn.javaxc.mvcwork.modules.notifier;
import cn.javaxc.mvcwork.controller.*;
import cn.javaxc.mvcwork.controller.web.PagedListInfo;
import cn.javaxc.mvcwork.framework.actions.*;
import cn.javaxc.mvcwork.framework.database.ConnectionElement;
import cn.javaxc.mvcwork.modules.admin.Contact;
import cn.javaxc.mvcwork.modules.file.*;
import cn.javaxc.mvcwork.modules.notifier.*;
import cn.javaxc.mvcwork.modules.site.*;
import cn.javaxc.mvcwork.util.common.*;
import java.lang.reflect.Constructor;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipOutputStream;
import java.util.Date;

public class NotificationUtils { 
	public final static String fs = "/";
  public static void sendCampaign(Connection db,Campaign thisCampaign,MVCConfig config,boolean hasExcp) throws Exception{
	  thisCampaign.setStatusId(Campaign.STARTED);
      if (thisCampaign.lockProcess(db) != 1) {
        return;
      }
	   String dbName = (String)config.get("gatekeeper.database");
      //Now that the campaign is locked, process it
      int campaignCount = 0;
      int sentCount = 0;
      boolean hasBcc = (thisCampaign.getBcc() != null && !"".equals(
          thisCampaign.getBcc()));
      boolean hasCc = (thisCampaign.getCc() != null && !"".equals(
          thisCampaign.getCc()));

      //Read the file attachments list, and copy into another FileItemList
      //with the clientFilename, and the server's filename for the notification
      FileItemList attachments = new FileItemList();
      FileItemList fileItemList = new FileItemList();
      fileItemList.setLinkModuleId("attachments");
      fileItemList.setLinkItemId(thisCampaign.getId());
      fileItemList.buildList();
      if (System.getProperty("DEBUG") != null) {
        if (fileItemList.size() > 0) {
          System.err.println(
              "Notifier-> Campaign file attachments: " + fileItemList.size());
        }
      }
      Iterator files = fileItemList.iterator();
      while (files.hasNext()) {
        FileItem thisItem = (FileItem) files.next();
        FileItem actualItem = new FileItem();
        actualItem.setClientFilename(thisItem.getClientFilename());
        actualItem.setDirectory(config.get("FILELIBRARY") + fs + dbName + fs + "communications" + fs);
        actualItem.setFilename(thisItem.getFilename());
        actualItem.setSize(thisItem.getSize());
        attachments.add(actualItem);
      }
      thisCampaign.buildMessageAttachments(db);
      //Adding message attachments 
      Iterator messageAttachments = thisCampaign.getMessageAttachments().iterator();
      while (messageAttachments.hasNext()) {
    	MessageAttachment messageAttachment = (MessageAttachment)messageAttachments.next();
        FileItem thisItem = messageAttachment.getFileItem(); 
        if (thisItem!=null) {
        thisItem.buildVersionList();
        FileItemVersion itemToDownload = thisItem.getVersion(thisItem.getVersion());
        FileItem actualItem = new FileItem();
        
        if (itemToDownload!=null) {           
        	actualItem.setClientFilename(thisItem.getClientFilename());

			actualItem.setDirectory(AppUtils.getModuleFileLibrary(config,thisItem.getLinkModuleId()));

           actualItem.setFilename(itemToDownload.getFilename());
           actualItem.setSize(thisItem.getSize());
		   actualItem.setEntered(thisItem.getEntered());
           attachments.add(actualItem);
        }  
        }
      }

      //Load in the recipients
      RecipientList recipientList = new RecipientList();
      recipientList.setCampaignId(thisCampaign.getId());
      recipientList.setHasNullSentDate(true);
      recipientList.setBuildContact(false);
      recipientList.buildList(db);
      //Generate a campaign run --> Information about when a campaign was processed
      int runId = -1;
      Iterator iList = recipientList.iterator();
      if (iList.hasNext()) {
        runId = thisCampaign.insertRun(db);
      } else {
        thisCampaign.setStatusId(Campaign.ERROR);
        thisCampaign.setStatus("No Recipients");
        thisCampaign.setBuildGroupMaps(true);
        thisCampaign.buildUserGroupMaps(db);
        thisCampaign.update(db);
      }
      //Send each recipient a message
      while (iList.hasNext()) {
        ++campaignCount;
        Recipient thisRecipient = (Recipient) iList.next();
//        Contact thisContact = new Contact(db, thisRecipient.getContactId());
		Contact thisContact=null;
        Notification thisNotification = new Notification();
        thisNotification.setHost((String) config.get("MAILSERVER"));
        thisNotification.setContactToNotify(thisRecipient.getContactId());
		thisNotification.setReplyMail(thisRecipient.getReplyMail());
        thisNotification.setModule("Communications Manager");
        thisNotification.setDatabaseName(dbName);
        thisNotification.setItemId(thisCampaign.getId());
        thisNotification.setFileAttachments(attachments);
        thisNotification.setCampaignType(thisCampaign.getType());
        thisNotification.setItemModified(thisCampaign.getActiveDate());
        if (thisNotification.isNew(db)) {
          thisNotification.setFrom(thisCampaign.getReplyTo());
          thisNotification.setSubject(thisCampaign.getSubject());
          thisNotification.setMessageIdToSend(thisCampaign.getMessageId());
          if (hasBcc) {
            thisNotification.setBcc(thisCampaign.getBcc());
            hasBcc = false;
          }
          if (hasCc) {
            thisNotification.setCc(thisCampaign.getCc());
            hasCc = false;
          }
          //If a survey is attached, encode the url for this recipient
          Template template = new Template();
          template.setText(thisCampaign.getMessage());
          String value = null;

		  
		  
		  if(thisContact!=null){
          //NOTE: The following items are the same as the ProcessMessage.java items
          template.addParseElement(
              "${name}", StringUtils.toHtml(thisContact.getNameFirstLast()));
          template.addParseElement(
              "${firstname}", StringUtils.toHtml(thisContact.getNameFirst()));
          template.addParseElement(
              "${lastname}", StringUtils.toHtml(thisContact.getNameLast()));
          template.addParseElement(
              "${company}", StringUtils.toHtml(thisContact.getCompany()));
          template.addParseElement(
              "${department}", StringUtils.toHtml(
                  thisContact.getDepartmentName()));
		}
			String baseURL = template.getValue("baseURL");
          template.addParseElement("${baseURL="+baseURL+"}","");
			String messageToSend = template.getParsedText();
			if (baseURL != null && !"".equals(baseURL)) {
				messageToSend = messageToSend.replace( "src=\"TTPFile.do?execute=StreamImage","src=\"http://" + baseURL +  "/ProcessFile.do?execute=StreamImage");
			}
          thisNotification.setMessageToSend(messageToSend);
          thisNotification.setType(thisCampaign.getSendMethodId());
          thisNotification.notifyContact(db);


          
          ++sentCount;
          thisRecipient.setRunId(thisNotification.getId());
          thisRecipient.setSentDate(
              new java.sql.Timestamp(System.currentTimeMillis()));
          thisRecipient.setStatusDate(
              new java.sql.Timestamp(System.currentTimeMillis()));
          thisRecipient.setStatusId(1);
          thisRecipient.setStatus(thisNotification.getStatus());
          if (System.getProperty("DEBUG") != null) {
            System.err.println(
                "Notifier-> Notification status: " + thisNotification.getStatus());
          }
          thisRecipient.update(db);
        }
        if (thisNotification.hasErrors()) {
			if (hasExcp){
				throw thisNotification.getErrorMessage();
			}
        }
      }
      if (campaignCount > 0) {
        
        thisCampaign.setStatusId(Campaign.FINISHED);
        thisCampaign.setRecipientCount(campaignCount);
        thisCampaign.setSentCount(sentCount);
        thisCampaign.setBuildGroupMaps(true);
        thisCampaign.update(db);
      }
  }	

}
